package model.prestamos.estado;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import model.cuota.Cuota;
import model.prestamos.Prestamo;

import org.junit.Test;

import excepciones.prestamos.NoSePuedeAprobarPrestamoException;
import excepciones.prestamos.NoSePuedePasarPrestamoAEnDeudaException;
import excepciones.prestamos.NoSePuedeRechazarPrestamoException;

/**
 * @author Lucas
 */
public class PrestamoEnDeudaTest {

	private EnDeuda prestamoEnDeuda = new EnDeuda();
	private Prestamo prestamoMock = mock(Prestamo.class);
	
	/**
	 * Verifica que un prestamo en deuda no se puede aprobar  
	 * @throws NoSePuedeAprobarPrestamoException
	 */
	@Test(expected=NoSePuedeAprobarPrestamoException.class)
	public void testNoSePuedeAprobarPrestamo() throws NoSePuedeAprobarPrestamoException{
		prestamoEnDeuda.aprobar(prestamoMock);
	}
	
	/**
	 * Verifica que un prestamo en deuda no se puede rechazar
	 * @throws NoSePuedeRechazarPrestamoException
	 */
	@Test(expected=NoSePuedeRechazarPrestamoException.class)
	public void testNoSePuedeRechazarPrestamo() throws NoSePuedeRechazarPrestamoException{
		prestamoEnDeuda.rechazar(prestamoMock, "motivo cualquiera");
	}
	
	/** Verifica que el prestamo en deuda puede recibir el pago de una cuota, 
	 *  y que el prestamo recibe el llamado a actualizar su estado */
	@Test
	public void testCobrarCuota(){
		Cuota cuotaImpaga = mock(Cuota.class);
		List<Cuota> cuotas = new ArrayList<Cuota>();
		cuotas.add(cuotaImpaga);
		
		when(prestamoMock.getCuotas()).thenReturn(cuotas);
		when(cuotaImpaga.estaPaga()).thenReturn(false);
		
		prestamoEnDeuda.cobrarCuota(prestamoMock);
		
		verify(prestamoMock).getCuotas();
		verify(cuotaImpaga).pagar();
		verify(prestamoMock).updateEstado();
		
	}
	
	/** Verifica que un prestamo en deuda no puede pasarse a En Deuda 
	 * @throws NoSePuedePasarPrestamoAEnDeudaException */
	@Test(expected=NoSePuedePasarPrestamoAEnDeudaException.class)
	public void testNoSePuedePasarPrestamoAEnDeuda() throws NoSePuedePasarPrestamoAEnDeudaException{
		prestamoEnDeuda.pasarPrestamoAEnDeuda(prestamoMock);
	}
	
	/** Verifica que un prestamo en deuda puede pasarse a Deuda incobrable */
	@Test
	public void testPuedePasarPrestamoDeFinalizadoAEnDeudaIncobrable(){
		prestamoEnDeuda.pasarPrestamoADeudorIncobrable(prestamoMock);
		verify(prestamoMock).aDeudaIncobrable();
	}
	
	/** Verifica que el prestamo no esta solicitado */
	@Test
	public void testPrestamoNoEsSolicitado(){
		assertFalse(prestamoEnDeuda.estaSolicitado());
	}
	
	/** Verifica que el prestamo no esta en curso */
	@Test
	public void testPrestamoEstaEnCurso(){
		assertFalse(prestamoEnDeuda.estaEnCurso());
	}
	
	/** Verifica que el prestamo esta en deuda */
	@Test
	public void testPrestamoNoEstaEnDeuda(){
		assertTrue(prestamoEnDeuda.estaEnDeuda());
	}
	
	/** Verifica que el prestamo no esta en deuda incobrable */
	@Test
	public void testPrestamoNoEstaEnDeudaIncobrable() {
		assertFalse(prestamoEnDeuda.estaEnDeudaIncobrable());
	}
	
	/** Verifica que el prestamo no esta finalizado */
	@Test
	public void testPrestamoNoEstaFinalizado() {
		assertFalse(prestamoEnDeuda.estaFinalizado());
	}

	/** Verifica que el prestamo no esta rechazado */
	@Test
	public void testPrestamoNoEstaRechazado() {
		assertFalse(prestamoEnDeuda.estaRechazado());
	}
	
	/** Verifica que un prestamo finalizado adeuda cuotas */
	@Test
	public void testPrestamoFinalizadoNoAdeudaCuotas(){
		assertFalse(prestamoEnDeuda.adeudaCuotas(prestamoMock));
	}
}
